package com.papercutting.platform.controller.admin;

import com.papercutting.platform.common.Result;
import com.papercutting.platform.dto.query.NewsQuery;
import com.papercutting.platform.dto.request.NewsRequest;
import com.papercutting.platform.dto.response.NewsResponse;
import com.papercutting.platform.dto.response.PageResult;
import com.papercutting.platform.entity.News;
import com.papercutting.platform.service.NewsService;
import com.papercutting.platform.util.EntityConverter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 管理员-活动资讯控制器
 */
@Slf4j
@RestController("adminNewsController")
@RequestMapping("/api/admin/news")
@RequiredArgsConstructor
@Validated
public class NewsController {
    
    private final NewsService newsService;
    
    /**
     * 创建活动资讯
     */
    @PostMapping
    public Result<Long> createNews(@Valid @RequestBody NewsRequest request) {
        log.info("创建活动资讯请求: {}", request.getTitle());

        News news = EntityConverter.toNews(request);
        
        // 如果状态为已发布且没有发布时间，设置当前时间为发布时间
        if (news.getStatus() == 1 && news.getPublishTime() == null) {
            news.setPublishTime(LocalDateTime.now());
        }
        
        News savedNews = newsService.save(news);

        return Result.success("活动资讯创建成功", savedNews.getId());
    }

    /**
     * 更新活动资讯
     */
    @PutMapping("/{id}")
    public Result<Void> updateNews(
            @PathVariable @NotNull Long id,
            @Valid @RequestBody NewsRequest request) {
        log.info("更新活动资讯请求: {}", id);

        News existingNews = newsService.findById(id);
        if (existingNews == null) {
            throw new RuntimeException("活动资讯不存在");
        }

        EntityConverter.updateNews(existingNews, request);
        
        // 如果状态为已发布且没有发布时间，设置当前时间为发布时间
        if (existingNews.getStatus() == 1 && existingNews.getPublishTime() == null) {
            existingNews.setPublishTime(LocalDateTime.now());
        }
        
        newsService.save(existingNews);

        return Result.success("活动资讯更新成功");
    }

    /**
     * 删除活动资讯
     */
    @DeleteMapping("/{id}")
    public Result<Void> deleteNews(@PathVariable @NotNull Long id) {
        log.info("删除活动资讯请求: {}", id);

        newsService.deleteById(id);

        return Result.success("活动资讯删除成功");
    }
    
    /**
     * 获取活动资讯详情
     */
    @GetMapping("/{id}")
    public Result<NewsResponse> getNewsDetail(@PathVariable @NotNull Long id) {
        log.info("获取活动资讯详情: {}", id);

        News news = newsService.findById(id);
        if (news == null) {
            throw new RuntimeException("活动资讯不存在");
        }

        NewsResponse response = EntityConverter.toNewsResponse(news);
        return Result.success(response);
    }

    /**
     * 分页查询活动资讯列表
     */
    @GetMapping("/page")
    public Result<PageResult<NewsResponse>> getNewsPage(NewsQuery query) {
        log.info("分页查询活动资讯列表: {}", query);

        Pageable pageable = PageRequest.of(query.getPage() - 1, query.getSize());
        Page<News> newsPage = newsService.findNewsList(query.getType(), query.getTitle(), query.getStatus(), pageable);

        List<NewsResponse> responseList = newsPage.getContent().stream()
                .map(EntityConverter::toNewsResponse)
                .collect(Collectors.toList());

        PageResult<NewsResponse> result = PageResult.of(responseList, newsPage.getTotalElements(),
                query.getPage(), query.getSize());

        return Result.success(result);
    }

    /**
     * 获取活动资讯列表（不分页）
     */
    @GetMapping("/list")
    public Result<List<NewsResponse>> getNewsList(NewsQuery query) {
        log.info("查询活动资讯列表: {}", query);

        List<News> newsList = newsService.findAll();
        List<NewsResponse> responseList = newsList.stream()
                .map(EntityConverter::toNewsResponse)
                .collect(Collectors.toList());

        return Result.success(responseList);
    }
    
    /**
     * 批量删除活动资讯
     */
    @DeleteMapping("/batch")
    public Result<Void> batchDeleteNews(@RequestBody List<Long> ids) {
        log.info("批量删除活动资讯: {}", ids);

        for (Long id : ids) {
            newsService.deleteById(id);
        }

        return Result.success("批量删除成功");
    }

    /**
     * 批量更新状态
     */
    @PutMapping("/batch/status")
    public Result<Void> batchUpdateStatus(@RequestBody Map<String, Object> params) {
        log.info("批量更新状态: {}", params);

        @SuppressWarnings("unchecked")
        List<Long> ids = (List<Long>) params.get("ids");
        Integer status = (Integer) params.get("status");

        // 批量更新状态
        for (Long id : ids) {
            News news = newsService.findById(id);
            if (news != null) {
                news.setStatus(status);
                newsService.save(news);
            }
        }

        return Result.success("批量更新状态成功");
    }

    /**
     * 更新活动资讯状态
     */
    @PutMapping("/{id}/status")
    public Result<Void> updateNewsStatus(
            @PathVariable @NotNull Long id,
            @RequestParam @NotNull Integer status) {
        log.info("更新活动资讯状态: id={}, status={}", id, status);

        News news = newsService.findById(id);
        if (news == null) {
            throw new RuntimeException("活动资讯不存在");
        }

        news.setStatus(status);
        
        // 如果状态为已发布且没有发布时间，设置当前时间为发布时间
        if (status == 1 && news.getPublishTime() == null) {
            news.setPublishTime(LocalDateTime.now());
        }
        
        newsService.save(news);

        return Result.success("状态更新成功");
    }

    /**
     * 获取统计信息
     */
    @GetMapping("/stats")
    public Result<Map<String, Object>> getNewsStats() {
        log.info("获取活动资讯统计信息");

        List<News> allNews = newsService.findAll();

        long totalCount = allNews.size();
        long activityCount = allNews.stream().filter(n -> n.getType() == 1).count();
        long publishedCount = allNews.stream().filter(n -> n.getStatus() == 1).count();
        long totalViews = allNews.stream().mapToLong(n -> n.getViewCount() != null ? n.getViewCount() : 0).sum();

        Map<String, Object> stats = Map.of(
            "totalCount", totalCount,
            "activityCount", activityCount,
            "publishedCount", publishedCount,
            "totalViews", totalViews
        );

        return Result.success(stats);
    }
}
